home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <AppleEvents.h>
- #include "Processor.h"
- #include "Modes.h"
- #include "Stack.h"
- #include "Keyboard.h"
- #include "Resources.h"
- #include "Preferences.h"
-
- extern Cursor commieCursor;
- extern void (* instruct[256]) ();
- extern byte cycletime[256];
- extern int programMode;
-
- byte interruptProcessor;
- static byte numLeftSameChar;
- static void ProcessPerLine(void);
- extern void ProcessorLoop(void);
-
- void CProcessorLoop(), M68kProcessorLoop(), IntProcessorLoop();
-
- void ProcessorLoop()
- {
- switch (globalPref.useProcessor)
- {
- case asmProcessor:
- #ifndef __MWERKS__
- M68kProcessorLoop();
- #else
- IntProcessorLoop();
- #endif
- break;
- case cProcessor:
- CProcessorLoop();
- break;
- case intCProcessor:
- IntProcessorLoop();
- break;
- }
- }
-
- void CProcessorLoop()
- {
- int scanLines, vicCalls;
- byte instructCode, oldMemoryMap, processorCycles, col;
- Str255 str;
-
- programMode=kRunning;
-
- ShowVICWindow();
-
- /* Set up window, cursor for running state */
- GetIndString(str, kWindowStrings, kRunningWindow);
- SetVICTitle(str);
- SetCursor(&commieCursor);
- ObscureCursor();
-
- /* Set up the memory dereferences, and store current map */
- oldMemoryMap=*RAMp1;
- SetUpMemoryMap();
-
- /* Some flags and counters necessray to be initialized */
- interruptProcessor=0;
- numLeftSameChar=0;
- processorCycles=0;
- scanLines=0;
- vicCalls=0;
-
- while (interruptProcessor==0)
- {
- instructCode = ImmediateByte(); pc++;
- processorCycles += cycletime[instructCode];
- (*instruct[instructCode])();
-
- /* Set up the memory map if it has changed */
- if (*RAMp1!=oldMemoryMap)
- {
- SetUpMemoryMap();
- oldMemoryMap=*RAMp1;
- }
-
- /* If we've done 35 cycles, we've gone through 1 scanline */
- if (processorCycles>35)
- {
- processorCycles=0;
-
- /* Update the current VIC scan register */
- if (++RAM[0xd012]==0) RAM[0xd011] ^= 128;
- RAM[0xd018] |=1;
-
- /* If we've gone through 350 lines, we've due for an interrupt */
- if (++scanLines>350)
- {
- scanLines=0;
-
- /* Set raster to 0 line */
- RAM[0xd012]=0;
- RAM[0xd011]&=127;
-
- /* Currently we just update the keyboard registers */
- ProcessPerLine();
- if (++vicCalls==2)
- {
- RedrawVIC();
- vicCalls=0;
- }
-
- /* Call interrupt routine if interrupts enabled */
- if ((flags&INT)==0)
- {
- PushWord(pc);
- Push(flags);
- pc=WordAt(IrqTo);
- }
- }
- }
-
- /* Set up the keyboard register according to precomputed values */
- RAM[0xdc01]=scanCode[RAM[0xdc00]];
- }
-
- /* Done processing, reset window, cursor */
- RedrawVIC();
- SetCursor(&qd.arrow);
- GetIndString(str, kWindowStrings, kSuspendedWindow);
- SetVICTitle(str);
-
- programMode=kSleeping;
- }
-
- extern void CPU(void);
-
- void M68kProcessorLoop()
- {
- #ifndef __MWERKS__
- int vicCalls;
- byte *d012, *d011, *d018;
- Str255 str;
-
- ShowVICWindow();
-
- /* Set up window, cursor for running state */
- GetIndString(str, kWindowStrings, kRunningWindow);
- SetVICTitle(str);
- SetCursor(&commieCursor);
- ObscureCursor();
-
- /* Initialize precomputed addresses (minimal speed gain) */
- d012=&RAM[0xd012];
- d011=&RAM[0xd011];
- d018=&RAM[0xd018];
-
- /* Store current map */
- SetUpMemoryMap();
-
- /* Some flags and counters necessary to be initialized */
- interruptProcessor=0;
- numLeftSameChar=0;
- vicCalls=0;
-
- while (interruptProcessor==0) {
- /* Most of the functionality of the CPU has been moved to this function.
- * This function will execute for 350 screen lines.
- */
- CPU();
-
- /* If we've gone through 350 lines, we've due for an interrupt */
- /* Set raster to 0 line */
- *d012=0;
- *d011&=127;
-
- /* Currently we just update the keyboard registers */
- ProcessPerLine();
-
- if (++vicCalls==2)
- {
- RedrawVIC();
- vicCalls=0;
- }
-
- /* Call interrupt routine if interrupts enabled */
- if ((flags&INT)==0)
- {
- PushWord(pc);
- Push(flags);
- pc=WordAt(IrqTo);
- }
- }
-
- /* Done processing, reset window, cursor */
- RedrawVIC();
- SetCursor(&qd.arrow);
- GetIndString(str, kWindowStrings, kSuspendedWindow);
- SetVICTitle(str);
- #endif
- }
-
-
- /* Called once per scanline, currently check for keypress or mouse button */
- static void ProcessPerLine()
- {
- EventRecord evt;
- WindowPtr theWind;
- int x;
- char theChar;
-
- /* We keep the same keyboard map for 1/30th of a second */
- if (numLeftSameChar==0)
- {
- numLeftSameChar=2;
-
- /* Check for any key or mouse press */
- if (GetNextEvent(-1, &evt)!=false)
- switch(evt.what)
- {
- case mouseDown:
- /* A mouseclick stops our simulation */
- MiniHandleMouseDown(evt);
- break;
-
- case updateEvt:
- theWind=(WindowPtr)evt.message;
- BeginUpdate(theWind);
- switch (GetWRefCon(theWind))
- {
- case kVICWindow:
- break;
- case kDirWindow:
- RedrawDir();
- break;
- case kAboutWindow:
- break;
- }
- EndUpdate(theWind);
- break;
-
- case app4Evt:
- if ((evt.message&1)==0) interruptProcessor=1;
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent(&evt);
- break;
-
- case keyDown:
- case autoKey:
- /* A keypress is simulated by fudging the CIA registers */
- theChar = evt.message&charCodeMask;
- if ((evt.modifiers&cmdKey)!=0) DoMenuChoice(MenuKey(theChar));
- else AppleScanKeyboard(evt.message&charCodeMask, evt.modifiers);
- }
-
- /* No keypress, so clear out keyboard register fudge */
- else
- {
- for (x=0; x<256; x++) scanCode[x]=0xff;
- SystemTask();
- }
- }
- else numLeftSameChar--;
- }
-
-
- MiniHandleMouseDown(event)
- EventRecord event;
- {
- WindowPtr theWind;
- GrafPtr gp;
- Point x;
- short thePart;
- extern Rect dragRect;
-
- thePart=FindWindow(event.where, &theWind);
- switch(thePart)
- {
- case inSysWindow:
- SystemClick(&event, theWind);
- interruptProcessor=1;
- break;
-
- case inDrag:
- if (GetWRefCon(theWind)==kVICWindow) DragVICWindow(&event);
- else DragWindow(theWind, event.where, &dragRect);
- break;
-
- case inMenuBar:
- DoMenuChoice(MenuSelect(event.where));
- break;
-
- case inContent:
- SelectWindow(theWind);
- interruptProcessor=1;
- break;
- }
- }
-
-
- void IntProcessorLoop()
- {
- int vicCalls;
- byte *d012, *d011, *d018;
- Str255 str;
-
- ShowVICWindow();
-
- /* Set up window, cursor for running state */
- GetIndString(str, kWindowStrings, kRunningWindow);
- SetVICTitle(str);
- SetCursor(&commieCursor);
- ObscureCursor();
-
- /* Initialize precomputed addresses (minimal speed gain) */
- d012=&RAM[0xd012];
- d011=&RAM[0xd011];
- d018=&RAM[0xd018];
-
- /* Store current map */
- SetUpMemoryMap();
-
- /* Some flags and counters necessary to be initialized */
- interruptProcessor=0;
- numLeftSameChar=0;
- vicCalls=0;
-
- while (interruptProcessor==0) {
- /* Most of the functionality of the CPU has been moved to this function.
- * This function will execute for 350 screen lines.
- */
- IntegratedProcessor(&a, &x, &y, &flags, &sp, &pc, memory, RAM);
-
- /* If we've gone through 350 lines, we've due for an interrupt */
- /* Set raster to 0 line */
- *d012=0;
- *d011&=127;
-
- /* Currently we just update the keyboard registers */
- ProcessPerLine();
-
- if (++vicCalls==2)
- {
- RedrawVIC();
- vicCalls=0;
- }
-
- /* Call interrupt routine if interrupts enabled */
- if ((flags&INT)==0)
- {
- PushWord(pc);
- Push(flags);
- pc=WordAt(IrqTo);
- }
- }
-
- /* Done processing, reset window, cursor */
- RedrawVIC();
- SetCursor(&qd.arrow);
- GetIndString(str, kWindowStrings, kSuspendedWindow);
- SetVICTitle(str);
- }
-